from rest_framework import serializers
from .models import Inform, InformRead
from apps.oaauth.serializers import UserSerializer, DepartmentSerializer
from apps.oaauth.models import OADepartment


class InformReadSerializer(serializers.ModelSerializer):
    class Meta:
        model = InformRead
        fields = "__all__"


class InformSerializer(serializers.ModelSerializer):
    """
    author 和 departments 字段使用了嵌套序列化，这意味着当你序列化一个 Inform 实例时，author 和 departments 字段会被序列化为它们相应的序列化器所定义的格式。
    UserSerializer 和 DepartmentSerializer 分别被用来序列化 Inform 的 author 和 departments 字段。

    reads 字段是一个多对多关系，通过 InformReadSerializer 序列化。
    这允许你显示与某个 Inform 实例相关联的所有 InformRead 实例，从而提供关于通知阅读状态的信息。
    """
    # 嵌套序列化
    author = UserSerializer(read_only=True)
    departments = DepartmentSerializer(many=True, read_only=True)
    # department_ids：是一个包含了部门id的列表
    # 如果后端要接受列表，那么就需要用到ListField: [1,2]
    """
    department_ids 字段是一个列表字段（ListField），它明确指出后端需要接受一个列表，这在 Django REST framework 中是通过 ListField 来实现的。
    write_only=True 属性表明这个字段只在数据创建或更新时使用，序列化时不会包含在响应中。
    
    
    """
    department_ids = serializers.ListField(write_only=True)
    reads = InformReadSerializer(many=True, read_only=True)

    class Meta:
        """
        public 字段被标记为 read_only_fields 的一部分。
        这意味着当你序列化一个 Inform 实例时，public 字段不会被序列化，但是可以被读取。
        """
        model = Inform # Meta 类定义了序列化器对应的模型是 Inform，并且指定了要序列化的所有字段。fields = "__all__" 表示所有字段都应该被包含在内。
        fields = "__all__"
        read_only_fields = ('public',) # read_only_fields 属性定义了一组只读字段，这些字段在序列化时会被包含，但在反序列化时会被忽略。

        # 重写保存Inform对象的create方法

        # 重写保存Inform对象的create方法
    def create(self, validated_data):
        request = self.context['request']
        """
        重写的 create 方法允许你自定义 Inform 实例的创建逻辑。
        在这个例子中，create 方法首先从 validated_data 中弹出
        
        department_ids 列表，然后根据列表中是否包含 0 来决定创建公开或私有的 Inform 实例。
        """
        department_ids = validated_data.pop("department_ids")
        # department_ids: ['0', '1', '2']
        # 对列表中的某个值都做相同的操作，那么可以借助map方法
        department_ids = list(map(lambda value: int(value), department_ids))
        # 如果 0 在 department_ids 列表中，将创建一个公开的 Inform 实例，其中 author 设置为当前用户。
        if 0 in department_ids:
            inform = Inform.objects.create(public=True, author=request.user, **validated_data)
        #否则，将创建一个私有的 Inform 实例，然后通过 inform.departments.set(departments) 设置其 departments 字段为列表中指定的部门。
        else:
            departments = OADepartment.objects.filter(id__in=department_ids).all()
            inform = Inform.objects.create(public=False, author=request.user, **validated_data)
            inform.departments.set(departments)
            inform.save()
        return inform


# 这行代码定义了一个名为 ReadInformSerializer 的序列化器类，继承自 Django REST framework 的serializers.Serializer。
# Serializer 类提供了一个灵活的方式来定义序列化和反序列化的逻辑，允许你为模型或非模型数据定义序列化器。
class ReadInformSerializer(serializers.Serializer):
    """
    这行代码在 ReadInformSerializer 类中创建了一个名为 inform_pk 的字段。IntegerField 表示这个字段是一个整数类型，error_messages={'required': "请传入inform的ID"} 部分定义了一个错误消息。
    如果请求中缺少 inform_pk 字段，Django REST framework 将返回一个错误响应，提示用户需要传入 inform 的 ID。
    """
    inform_pk = serializers.IntegerField(error_messages={'required': "请传入inform的ID"})
